﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Routing;
using Microsoft.AspNet.StaticFiles;
using Microsoft.AspNet.FileProviders;
using System;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.PlatformAbstractions;
using System.Runtime.InteropServices;
using System.IO;
using Newtonsoft.Json;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNet.WebSockets.Server;
using Microsoft.AspNet.HttpOverrides;
using System.Net.WebSockets;
using System.Dynamic;

namespace CardWarWEB
{


    public class Startup
    {

        public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
        {
            localConf.env = env;
            localConf.appEnv = appEnv;
        }


        public void ConfigureServices(IServiceCollection services)
        {
            services.AddCaching();
            services.AddSession(s => { s.IdleTimeout = TimeSpan.FromMinutes(2); });
            services.AddMvc();
        }


        public void Configure(IApplicationBuilder app)
        {
            app.UseSession();
            WebSocketOptions wsop = new WebSocketOptions();
            wsop.ReceiveBufferSize = 16 * 1024;
            wsop.KeepAliveInterval = TimeSpan.FromMinutes(30);
            app.UseWebSockets(wsop);
            localServer.ApplicationBasePath = Server.GetApplicationBasePath();

            FileExtensionContentTypeProvider provider = new FileExtensionContentTypeProvider(Conf.mappings);
            app.UseStaticFiles(new StaticFileOptions() { ServeUnknownFileTypes = false, ContentTypeProvider = provider });
            app.UseStatusCodePages(status =>
            {
                bool over = false;
                status.Run(context =>
                {
                    if (over)
                    {
                        return Task.Delay(100);
                    }
                    over = true;
                    return Task.Run(delegate { context.Response.Redirect(context.Request.PathBase + "/Error/" + context.Response.StatusCode.ToString()); over = false; });


                });

            });
            app.UseDeveloperExceptionPage();
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action}",
                    defaults: new { controller = "Welcome", action = "Index" });

            });

            app.UseOverrideHeaders(new OverrideHeaderMiddlewareOptions
            {
                ForwardedOptions = ForwardedHeaders.XForwardedFor |
                           ForwardedHeaders.XForwardedProto
            });

            if (Directory.Exists("/v"))
            {
                if (File.Exists("/v/WebConfigs.data"))
                {
                    FileStream fs = new FileStream("/v/WebConfigs.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    Conf.WebConfigs = (WebConfig)bf.Deserialize(fs);
                    fs.Close();
                }
                else
                {
                    FileStream fs = new FileStream("/v/WebConfigs.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, Conf.WebConfigs);
                    fs.Close();
                }

                if (File.Exists("/v/AreaThreads.data"))
                {
                    FileStream fs = new FileStream("/v/AreaThreads.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    Conf.AreaThreads = (Dictionary<int, List<int>>)bf.Deserialize(fs);
                    fs.Close();
                }
                else
                {
                    FileStream fs = new FileStream("/v/AreaThreads.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, Conf.AreaThreads);
                    fs.Close();
                }

                if (File.Exists("/v/Users.data"))
                {
                    FileStream fs = new FileStream("/v/Users.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    Conf.Users = (Dictionary<string, UserConfig>)bf.Deserialize(fs);
                    fs.Close();
                }
                else
                {
                    FileStream fs = new FileStream("/v/Users.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, Conf.Users);
                    fs.Close();
                }

                if (File.Exists("/v/Threads.data"))
                {
                    FileStream fs = new FileStream("/v/Threads.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    Conf.Threads = (Dictionary<int, PostThread>)bf.Deserialize(fs);
                    fs.Close();
                }
                else
                {
                    FileStream fs = new FileStream("/v/Threads.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, Conf.Threads);
                    fs.Close();
                }

                if (File.Exists("/v/Replys.data"))
                {
                    FileStream fs = new FileStream("/v/Replys.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    Conf.Replys = (Dictionary<int, PostReply>)bf.Deserialize(fs);
                    fs.Close();
                }
                else
                {
                    FileStream fs = new FileStream("/v/Replys.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, Conf.Replys);
                    fs.Close();
                }

                if (File.Exists("/v/ThreadReplys.data"))
                {
                    FileStream fs = new FileStream("/v/ThreadReplys.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    Conf.ThreadReplys = (Dictionary<int, List<int>>)bf.Deserialize(fs);
                    fs.Close();
                }
                else
                {
                    FileStream fs = new FileStream("/v/ThreadReplys.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, Conf.ThreadReplys);
                    fs.Close();
                }

                if (File.Exists("/v/Emails.data"))
                {
                    FileStream fs = new FileStream("/v/Emails.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    Conf.Emails = (List<string>)bf.Deserialize(fs);
                    fs.Close();
                }
                else
                {
                    FileStream fs = new FileStream("/v/Emails.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, Conf.Emails);
                    fs.Close();
                }
            }
            else
            {
                if (File.Exists(Server.GetApplicationBasePath() + "/WebConfigs.data"))
                {
                    FileStream fs = new FileStream(Server.GetApplicationBasePath() + "/WebConfigs.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    Conf.WebConfigs = (WebConfig)bf.Deserialize(fs);
                    fs.Close();
                }
                else
                {
                    FileStream fs = new FileStream(Server.GetApplicationBasePath() + "/WebConfigs.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, Conf.WebConfigs);
                    fs.Close();
                }

                if (File.Exists(Server.GetApplicationBasePath() + "/AreaThreads.data"))
                {
                    FileStream fs = new FileStream(Server.GetApplicationBasePath() + "/AreaThreads.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    Conf.AreaThreads = (Dictionary<int, List<int>>)bf.Deserialize(fs);
                    fs.Close();
                }
                else
                {
                    FileStream fs = new FileStream(Server.GetApplicationBasePath() + "/AreaThreads.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, Conf.AreaThreads);
                    fs.Close();
                }

                if (File.Exists(Server.GetApplicationBasePath() + "/Users.data"))
                {
                    FileStream fs = new FileStream(Server.GetApplicationBasePath() + "/Users.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    Conf.Users = (Dictionary<string, UserConfig>)bf.Deserialize(fs);
                    fs.Close();
                }
                else
                {
                    FileStream fs = new FileStream(Server.GetApplicationBasePath() + "/Users.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, Conf.Users);
                    fs.Close();
                }

                if (File.Exists(Server.GetApplicationBasePath() + "/Threads.data"))
                {
                    FileStream fs = new FileStream(Server.GetApplicationBasePath() + "/Threads.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    Conf.Threads = (Dictionary<int, PostThread>)bf.Deserialize(fs);
                    fs.Close();
                }
                else
                {
                    FileStream fs = new FileStream(Server.GetApplicationBasePath() + "/Threads.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, Conf.Threads);
                    fs.Close();
                }


                if (File.Exists(Server.GetApplicationBasePath() + "/Replys.data"))
                {
                    FileStream fs = new FileStream(Server.GetApplicationBasePath() + "/Replys.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    Conf.Replys = (Dictionary<int, PostReply>)bf.Deserialize(fs);
                    fs.Close();
                }
                else
                {
                    FileStream fs = new FileStream(Server.GetApplicationBasePath() + "/Replys.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, Conf.Replys);
                    fs.Close();
                }

                if (File.Exists(Server.GetApplicationBasePath() + "/ThreadReplys.data"))
                {
                    FileStream fs = new FileStream(Server.GetApplicationBasePath() + "/ThreadReplys.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    Conf.ThreadReplys = (Dictionary<int, List<int>>)bf.Deserialize(fs);
                    fs.Close();
                }
                else
                {
                    FileStream fs = new FileStream(Server.GetApplicationBasePath() + "/ThreadReplys.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, Conf.ThreadReplys);
                    fs.Close();
                }


                if (File.Exists(Server.GetApplicationBasePath() + "/Emails.data"))
                {
                    FileStream fs = new FileStream(Server.GetApplicationBasePath() + "/Emails.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    Conf.Emails = (List<string>)bf.Deserialize(fs);
                    fs.Close();
                }
                else
                {
                    FileStream fs = new FileStream(Server.GetApplicationBasePath() + "/Emails.data", FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, Conf.Emails);
                    fs.Close();
                }

            }

            /*new Thread((ThreadStart)delegate
            {
                System.Timers.Timer T = new System.Timers.Timer(1000);
                T.Elapsed += delegate { Console.WriteLine(Conf.onlines.Count); };
                T.Start();
            }).Start();*/


        }
    }
}
